package com.hsteach.service.rota;

import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.google.common.collect.Lists;
import com.hsteach.common.config.App;
import com.hsteach.common.config.AppConfig;
import com.hsteach.common.core.domain.model.AuthInfo;
import com.hsteach.common.exception.ServiceException;
import com.hsteach.common.utils.DateUtils;
import com.hsteach.common.utils.DistinctKeyUtil;
import com.hsteach.common.utils.SecurityUtils;
import com.hsteach.common.utils.sign.Base64;
import com.hsteach.dao.domain.rota.RotaDetail;
import com.hsteach.dao.domain.rota.RotaPerson;
import com.hsteach.dao.domain.todothings.Todothings;
import com.hsteach.dao.mapper.rota.RotaDetailMapper;
import com.hsteach.dao.mapper.rota.RotaPersonMapper;
import com.hsteach.dao.mapper.todothings.TodothingsMapper;
import com.hsteach.enums.*;
import com.hsteach.framework.feign.client.xgk.dto.ret.GetTeacherRet;
import com.hsteach.service.third.MessageService;
import com.hsteach.service.third.XgkService;
import com.hsteach.service.todothings.TodothingsService;
import com.hsteach.web.controller.rota.dto.AddRotaTransferDto;
import com.hsteach.web.controller.rota.dto.ReviewRotaTransferDto;
import jodd.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.hsteach.dao.mapper.rota.RotaTransferMapper;
import com.hsteach.dao.domain.rota.RotaTransfer;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 值班调换Service业务层处理
 * 
 * @author fanxquer
 * @date 2023-10-22
 */
@Service
public class RotaTransferService
{
    @Autowired
    private RotaTransferMapper rotaTransferMapper;

    @Autowired
    private RotaDetailMapper rotaDetailMapper;

    @Autowired
    private RotaPersonMapper rotaPersonMapper;

    @Autowired
    private RotaDetailService rotaDetailService;

    @Autowired
    private XgkService xgkService;

    @Autowired
    private MessageService messageService;

    @Autowired
    private TodothingsService todothingsService;

    @Autowired
    private AppConfig appConfig;

    /**
     * 查询值班调换
     * 
     * @param id 值班调换主键
     * @return 值班调换
     */
    public RotaTransfer selectRotaTransferById(Long id)
    {
        return rotaTransferMapper.selectRotaTransferById(id);
    }

    /**
     * 查询值班调换列表
     * 
     * @param rotaTransfer 值班调换
     * @return 值班调换
     */
    public List<RotaTransfer> selectRotaTransferList(RotaTransfer rotaTransfer)
    {
        return rotaTransferMapper.selectRotaTransferList(rotaTransfer);
    }

    public List<RotaDetail> getMyFromDate(Long rotaId) {
        List<RotaDetail> rotaDetails = rotaDetailService.listByPersonId(rotaId, SecurityUtils.getAuthInfo().getPersonId());
        return rotaDetails.stream().filter(e -> e.getDutyDate().compareTo(DateUtils.getNowyyyyMMdd()) >= 0)
                .sorted(Comparator.comparing(RotaDetail::getDutyDate)).collect(Collectors.toList());
    }

    public List<RotaPerson> listToPerson(Long rotaId, String transDate) {
        RotaDetail query = new RotaDetail();
        query.setRotaId(rotaId);
        query.setDelStatus(BooleanEnum.TRUE.getCode());
        query.setBeginDate(DateUtils.getNowyyyyMMdd());
        List<RotaDetail> rotaDetails = rotaDetailMapper.selectRotaDetailList(query);
        if (rotaDetails.size() == 0) {
            return Lists.newArrayList();
        }

//        RotaDetail query2 = new RotaDetail();
//        query2.setRotaId(rotaId);
//        query2.setDelStatus(BooleanEnum.TRUE.getCode());
//        query2.setDutyDate(DateUtils.parseDate(transDate));
//        List<RotaDetail> rotaDetails2 = rotaDetailMapper.selectRotaDetailList(query2);
//        List<String> fromPeronIds;
//        if (rotaDetails2.size() > 0) {
//            List<Long> fromIds = rotaDetails2.stream().map(RotaDetail::getId).collect(Collectors.toList());
//            RotaPerson personQuery2 = new RotaPerson();
//            personQuery2.setRotaDetailIds(fromIds);
//            List<RotaPerson> fromRotaPeople = rotaPersonMapper.selectRotaPersonList(personQuery2);
//            if (fromRotaPeople.size() > 0) {
//                fromPeronIds = fromRotaPeople.stream().map(RotaPerson::getPersonId).collect(Collectors.toList());
//            } else {
//                fromPeronIds = Lists.newArrayList();
//            }
//        } else {
//            fromPeronIds = Lists.newArrayList();
//        }


        List<Long> ids = rotaDetails.stream().map(RotaDetail::getId).collect(Collectors.toList());
        RotaPerson personQuery = new RotaPerson();
        personQuery.setRotaDetailIds(ids);
        List<RotaPerson> rotaPeople = rotaPersonMapper.selectRotaPersonList(personQuery);
        String personId = SecurityUtils.getAuthInfo().getPersonId();
        return rotaPeople.stream().filter(e -> !personId.equals(e.getPersonId()))
                .filter(DistinctKeyUtil.distinctByKey(RotaPerson::getPersonId)).collect(Collectors.toList());
    }

    public List<RotaDetail> listToDate(Long rotaId, String toPersonId) {
        List<RotaDetail> rotaDetails = rotaDetailService.listByPersonIdAndMNotMe(rotaId, toPersonId, SecurityUtils.getAuthInfo().getPersonId());
        return rotaDetails.stream().filter(e -> e.getDutyDate().compareTo(DateUtils.getNowyyyyMMdd()) >= 0).collect(Collectors.toList());
    }

    /**
     * 新增值班调换
     * 
     * @param rotaTransfer 值班调换
     * @return 结果
     */
    public int insertRotaTransfer(RotaTransfer rotaTransfer)
    {
        rotaTransfer.setCreateTime(DateUtils.getNowDate());
        return rotaTransferMapper.insertRotaTransfer(rotaTransfer);
    }

    public int add(AddRotaTransferDto dto)
    {
        RotaTransfer transfer = new RotaTransfer();
        BeanUtils.copyProperties(dto, transfer);

        RotaDetail detailQuery = new RotaDetail();
        detailQuery.setRotaId(dto.getRotaId());
        detailQuery.setDutyDate(dto.getFromDate());
        List<RotaDetail> fromDetails = rotaDetailMapper.selectRotaDetailList(detailQuery);
        if (fromDetails.size() == 0) {
            throw new ServiceException("未查找到原值班日期");
        }

        detailQuery.setDutyDate(dto.getToDate());
        List<RotaDetail> toDetails = rotaDetailMapper.selectRotaDetailList(detailQuery);
        if (toDetails.size() == 0) {
            throw new ServiceException("未查找到目标值班日期");
        }
        AuthInfo authInfo = SecurityUtils.getAuthInfo();

        List<Long> detailIds = fromDetails.stream().map(RotaDetail::getId).collect(Collectors.toList());
        RotaPerson personQuery = new RotaPerson();
        personQuery.setRotaDetailIds(detailIds);
        List<RotaPerson> fromRotaPeople = rotaPersonMapper.selectRotaPersonList(personQuery);
        if (fromRotaPeople.stream().filter(e -> e.getPersonId().equals(dto.getToPersonId())).count() > 0) {
            throw new ServiceException(dto.getToPersonName() + "在" + DateUtils.parseDateToStr("yyyy-MM-dd", dto.getFromDate()) + "已有值班，请选择其他人员");
        }

        transfer.setFromDetailId(fromDetails.get(0).getId());
        transfer.setToDetailId(toDetails.get(0).getId());
        transfer.setFromPersonId(authInfo.getPersonId());
        transfer.setFromPersonName(authInfo.getName());
        transfer.setTransferStatus(TransferStatusEnum.APPLY.getCode());
        transfer.setCreateBy(authInfo.getPersonId());
        int i = rotaTransferMapper.insertRotaTransfer(transfer);

        sendMsg(dto.getToPersonId(), authInfo.getName(), transfer.getId());
        return i;
    }

    public void sendMsg(String toPersonId, String fromName, Long businessKey) {
        List<GetTeacherRet> teachers = xgkService.getTeachers(SecurityUtils.getAuthInfo().getId());
        Map<String, String> teacherMap = teachers.stream().filter(e -> StringUtil.isNotEmpty(e.getT_userID())).collect(Collectors.toMap(GetTeacherRet::getPersonId, GetTeacherRet::getT_userID, (v1, v2) -> v2));
        String msg = fromName + "申请与您调换值班时间，请审核。";
        if (teacherMap.containsKey(toPersonId)) {
            AuthInfo authInfo = SecurityUtils.getAuthInfo();
            String appId = authInfo.getAppId();
            App app = appConfig.getConfig().get(appId);
            if (app == null) {
                throw new ServiceException("未配置消息跳转地址");
            }
            String eStr = "/change-shift/details?id=" + businessKey + "&type=approve";
            String encode = Base64.encode(eStr.getBytes(StandardCharsets.UTF_8));
//                String encode = URLEncoder.encode(eStr, "UTF-8");
            String params = "&e=" + encode ;
            String url = app.getRedirectUrl() + params;
            String s = messageService.addTodothings(msg, teacherMap.get(toPersonId), SecurityUtils.getAuthInfo().getOrganizeId(), url, MsgTypeEnum.TRANSFER_ROTA);
//            messageService.sendMsg(msg, Lists.newArrayList(teacherMap.get(toPersonId)), MsgTypeEnum.TRANSFER_ROTA);
            if (s != null) {
                Todothings todothings = new Todothings();
                todothings.setBusinessType(TodothingTypeEnum.ROTA_APPLY.getType());
                todothings.setBusinessKey(businessKey.toString());
                todothings.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
                todothings.setTodothingsId(s);
                todothings.setCreateBy(SecurityUtils.getAuthInfo().getPersonId());
                todothingsService.insertTodothings(todothings);
            }
        }
    }

    private void sendPassMsg(String toPersonId, String name, Long id) {
        List<GetTeacherRet> teachers = xgkService.getTeachers(SecurityUtils.getAuthInfo().getId());
        Map<String, String> teacherMap = teachers.stream().filter(e -> StringUtil.isNotEmpty(e.getT_userID())).collect(Collectors.toMap(GetTeacherRet::getPersonId, GetTeacherRet::getT_userID, (v1, v2) -> v2));
        String msg = "您与" + name + "老师申请调换值班时间，已通过";
        if (teacherMap.containsKey(toPersonId)) {
            AuthInfo authInfo = SecurityUtils.getAuthInfo();
            String appId = authInfo.getAppId();
            App app = appConfig.getConfig().get(appId);
            if (app == null) {
                throw new ServiceException("未配置消息跳转地址");
            }
            String eStr = "/change-shift/details?id=" + id + "&type=apply";
            String encode = Base64.encode(eStr.getBytes(StandardCharsets.UTF_8));
            String params = "&e=" + encode ;
            String url = app.getRedirectUrl() + params;
            String content = "<p>" + msg + "<a href=\"" + url + "\">跳转进应用</a></p>";
//            messageService.addTodothings(msg, teacherMap.get(toPersonId), SecurityUtils.getAuthInfo().getOrganizeId(), "/test", MsgTypeEnum.TRANSFER_ROTA);
            messageService.sendMsg(content, Lists.newArrayList(teacherMap.get(toPersonId)), MsgTypeEnum.TRANSFER_ROTA, msg);
            // 处理待办
            Todothings query = new Todothings();
            query.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
            query.setBusinessType(TodothingTypeEnum.ROTA_APPLY.getType());
            query.setBusinessKey(id.toString());
            List<Todothings> todothings = todothingsService.selectTodothingsList(query);
            if (!CollectionUtils.isEmpty(todothings)) {
                String todothingsId = todothings.get(0).getTodothingsId();
                messageService.dealTodothings(todothingsId);
            }
        }
    }

    /**
     * 调班通过后发送信息通知领导
     * @param transfer
     */
    private void noticeLeaderMsg(RotaTransfer transfer) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        String appId = authInfo.getAppId();
        App app = appConfig.getConfig().get(appId);
        if (app == null) {
            throw new ServiceException("未配置消息跳转地址");
        }
        List<GetTeacherRet> teachers = xgkService.getTeachers(SecurityUtils.getAuthInfo().getId());
        Map<String, String> teacherMap = teachers.stream().filter(e -> StringUtil.isNotEmpty(e.getT_userID())).collect(Collectors.toMap(GetTeacherRet::getPersonId, GetTeacherRet::getT_userID, (v1, v2) -> v2));
        // 查询调换日期
        RotaDetail fromDetail = rotaDetailMapper.selectRotaDetailById(transfer.getFromDetailId());
        RotaDetail toDetail = rotaDetailMapper.selectRotaDetailById(transfer.getToDetailId());
        // 查询调换日期对应的领导
        RotaPerson leaderQuery = new RotaPerson();
        leaderQuery.setRotaDetailId(transfer.getFromDetailId());
        leaderQuery.setDutyRole(DutyRoleEnum.LEADER.getCode());
        List<RotaPerson> fromLeaders = rotaPersonMapper.selectRotaPersonList(leaderQuery);
        leaderQuery.setRotaDetailId(transfer.getToDetailId());
        List<RotaPerson> toLeaders = rotaPersonMapper.selectRotaPersonList(leaderQuery);

        // 向发起调班人的领导发送通知，过滤自己
        List<String> fromUserIds = fromLeaders.stream().filter(e -> e.getPersonId().equals(transfer.getFromPersonId()))
                .filter(e -> teacherMap.containsKey(e.getPersonId())).map(e -> teacherMap.get(e.getPersonId())).collect(Collectors.toList());
        if (!fromUserIds.isEmpty()) {
            String msg = DateUtils.parseDateToStr("yyyy年MM月dd日", fromDetail.getDutyDate())
                    + "的值班，" + transfer.getFromPersonName() + " 已与 " + transfer.getToPersonName() + " 调班";
            String eStr = "/duty-roster?id=" + fromDetail.getRotaId();
            String encode = Base64.encode(eStr.getBytes(StandardCharsets.UTF_8));
            String params = "&e=" + encode ;
            String url = app.getRedirectUrl() + params;
            String content = "<p>" + msg + "<a href=\"" + url + "\">跳转进应用</a></p>";
            messageService.sendMsg(content, fromUserIds, MsgTypeEnum.TRANSFER_ROTA, msg);
        }
        // 向被调班人的领导发送通知，过滤自己
        List<String> toUserIds = toLeaders.stream().filter(e -> !e.getPersonId().equals(transfer.getToPersonId()))
                .filter(e -> teacherMap.containsKey(e.getPersonId())).map(e -> teacherMap.get(e.getPersonId())).collect(Collectors.toList());
        if (!toUserIds.isEmpty()) {
            String msg = DateUtils.parseDateToStr("yyyy年MM月dd日", toDetail.getDutyDate())
                    + "的值班，" + transfer.getToPersonName() + " 已与 " + transfer.getFromPersonName() + " 调班";
            String eStr = "/duty-roster?id=" + toDetail.getRotaId();
            String encode = Base64.encode(eStr.getBytes(StandardCharsets.UTF_8));
            String params = "&e=" + encode ;
            String url = app.getRedirectUrl() + params;
            String content = "<p>" + msg + "<a href=\"" + url + "\">跳转进应用</a></p>";
            messageService.sendMsg(content, toUserIds, MsgTypeEnum.TRANSFER_ROTA, msg);
        }
    }

    private void sendRejectMsg(String toPersonId, String name, Long id) {
        List<GetTeacherRet> teachers = xgkService.getTeachers(SecurityUtils.getAuthInfo().getId());
        Map<String, String> teacherMap = teachers.stream().filter(e -> StringUtil.isNotEmpty(e.getT_userID())).collect(Collectors.toMap(GetTeacherRet::getPersonId, GetTeacherRet::getT_userID, (v1, v2) -> v2));
        String msg = "您与" + name + "老师申请调换值班时间，已被拒绝。";
        if (teacherMap.containsKey(toPersonId)) {
            AuthInfo authInfo = SecurityUtils.getAuthInfo();
            String appId = authInfo.getAppId();
            App app = appConfig.getConfig().get(appId);
            if (app == null) {
                throw new ServiceException("未配置消息跳转地址");
            }
            String eStr = "/change-shift/details?id=" + id + "&type=apply";
            String encode = Base64.encode(eStr.getBytes(StandardCharsets.UTF_8));
            String params = "&e=" + encode ;
            String url = app.getRedirectUrl() + params;
            String content = "<p>" + msg + "<a href=\"" + url + "\">跳转进应用</a></p>";
            messageService.sendMsg(content, Lists.newArrayList(teacherMap.get(toPersonId)), MsgTypeEnum.TRANSFER_ROTA, msg);
            // 处理待办
            Todothings query = new Todothings();
            query.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
            query.setBusinessType(TodothingTypeEnum.ROTA_APPLY.getType());
            query.setBusinessKey(id.toString());
            List<Todothings> todothings = todothingsService.selectTodothingsList(query);
            if (!CollectionUtils.isEmpty(todothings)) {
                String todothingsId = todothings.get(0).getTodothingsId();
                messageService.dealTodothings(todothingsId);
            }
        }
    }

    /**
     * 修改值班调换
     * 
     * @param rotaTransfer 值班调换
     * @return 结果
     */
    public int updateRotaTransfer(RotaTransfer rotaTransfer)
    {
        rotaTransfer.setUpdateTime(DateUtils.getNowDate());
        return rotaTransferMapper.updateRotaTransfer(rotaTransfer);
    }

    @Transactional(rollbackFor = Exception.class)
    public int review(ReviewRotaTransferDto dto)
    {
        RotaTransfer rotaTransfer = rotaTransferMapper.selectRotaTransferById(dto.getId());
        if (rotaTransfer == null) {
            throw new ServiceException("未找到调班记录");
        }
        if (BooleanEnum.TRUE.getCode().equals(dto.getReviewStatus())) {
            RotaPerson query = new RotaPerson();
            query.setRotaDetailId(rotaTransfer.getFromDetailId());
            query.setPersonId(rotaTransfer.getFromPersonId());
            List<RotaPerson> formPerson = rotaPersonMapper.selectRotaPersonList(query);
            query.setRotaDetailId(rotaTransfer.getToDetailId());
            query.setPersonId(rotaTransfer.getToPersonId());
            List<RotaPerson> toPerson = rotaPersonMapper.selectRotaPersonList(query);
            if (CollectionUtils.isEmpty(formPerson) || CollectionUtils.isEmpty(toPerson)) {
                throw new ServiceException("调班数据已变更，无法通过");
            }
            RotaPerson fromUpdate = formPerson.get(0);
            RotaPerson toUpdate = toPerson.get(0);
            String fromMobile = fromUpdate.getPersonMobile();
            fromUpdate.setPersonId(rotaTransfer.getToPersonId());
            fromUpdate.setPersonName(rotaTransfer.getToPersonName());
            fromUpdate.setPersonMobile(toUpdate.getPersonMobile());
            toUpdate.setPersonId(rotaTransfer.getFromPersonId());
            toUpdate.setPersonName(rotaTransfer.getFromPersonName());
            toUpdate.setPersonMobile(fromMobile);
            rotaPersonMapper.updateRotaPerson(fromUpdate);
            rotaPersonMapper.updateRotaPerson(toUpdate);
            sendPassMsg(rotaTransfer.getFromPersonId(), rotaTransfer.getToPersonName(), dto.getId());
            noticeLeaderMsg(rotaTransfer);
        } else {
            sendRejectMsg(rotaTransfer.getFromPersonId(), rotaTransfer.getToPersonName(), dto.getId());
        }

        RotaTransfer update = new RotaTransfer();
        update.setId(dto.getId());
        update.setTransferStatus(dto.getReviewStatus());
        update.setReviewContent(dto.getReviewContent());
        update.setUpdateBy(SecurityUtils.getAuthInfo().getPersonId());
        update.setUpdateTime(DateUtils.getNowDate());
        return rotaTransferMapper.updateRotaTransfer(update);
    }

    /**
     * 批量删除值班调换
     * 
     * @param ids 需要删除的值班调换主键
     * @return 结果
     */
    public int deleteRotaTransferByIds(Long[] ids)
    {
        return rotaTransferMapper.deleteRotaTransferByIds(ids);
    }

    /**
     * 删除值班调换信息
     * 
     * @param id 值班调换主键
     * @return 结果
     */
    public int deleteRotaTransferById(Long id)
    {
        return rotaTransferMapper.deleteRotaTransferById(id);
    }
}
